"""
数据API路由

提供数据管理和访问的API接口。
"""

from typing import Dict, List, Any, Optional, Union
from datetime import datetime, date
from fastapi import APIRouter, HTTPException, Depends, Query, Path, UploadFile, File
from pydantic import BaseModel, Field

from ..data.data_manager import DataManager
from ..data.data_quality import DataQualityChecker
from ..data.data_cache import DataCache
from ..dependencies import get_data_manager, get_data_quality_checker, get_data_cache


router = APIRouter(prefix="/data", tags=["data"])


# 请求模型
class DataQueryRequest(BaseModel):
    """数据查询请求模型"""
    data_type: str = Field(..., description="数据类型")
    symbols: Optional[List[str]] = Field(None, description="标的代码列表")
    start_date: Optional[date] = Field(None, description="开始日期")
    end_date: Optional[date] = Field(None, description="结束日期")
    fields: Optional[List[str]] = Field(None, description="字段列表")
    filters: Dict[str, Any] = Field(default_factory=dict, description="筛选条件")
    limit: Optional[int] = Field(None, ge=1, le=10000, description="返回记录数限制")


class DataUploadRequest(BaseModel):
    """数据上传请求模型"""
    data_type: str = Field(..., description="数据类型")
    source: str = Field(..., description="数据源")
    metadata: Dict[str, Any] = Field(default_factory=dict, description="元数据")
    overwrite: bool = Field(default=False, description="是否覆盖已存在数据")


class DataValidationRequest(BaseModel):
    """数据验证请求模型"""
    data_type: str = Field(..., description="数据类型")
    data: List[Dict[str, Any]] = Field(..., description="待验证数据")
    rules: Optional[Dict[str, Any]] = Field(None, description="验证规则")


class CacheRequest(BaseModel):
    """缓存请求模型"""
    key: str = Field(..., description="缓存键")
    data: Any = Field(..., description="缓存数据")
    ttl: Optional[int] = Field(None, ge=1, description="过期时间(秒)")


# 响应模型
class DataResponse(BaseModel):
    """数据响应模型"""
    data: List[Dict[str, Any]]
    total: int
    data_type: str
    query_time: datetime
    metadata: Dict[str, Any] = {}


class DataSourceInfo(BaseModel):
    """数据源信息模型"""
    source_id: str
    name: str
    description: Optional[str] = None
    data_types: List[str]
    status: str
    last_update: Optional[datetime] = None
    update_frequency: Optional[str] = None
    quality_score: float = 0.0
    metadata: Dict[str, Any] = {}


class DataQualityReport(BaseModel):
    """数据质量报告模型"""
    data_type: str
    total_records: int
    quality_score: float
    issues: List[Dict[str, Any]]
    recommendations: List[str]
    check_time: datetime
    details: Dict[str, Any] = {}


class DataStatistics(BaseModel):
    """数据统计模型"""
    data_type: str
    record_count: int
    date_range: Dict[str, Optional[date]]
    field_statistics: Dict[str, Dict[str, Any]]
    update_frequency: Dict[str, int]
    quality_metrics: Dict[str, float]


# API端点
@router.get("/query", response_model=DataResponse)
async def query_data(
    data_type: str = Query(..., description="数据类型"),
    symbols: Optional[str] = Query(None, description="标的代码，多个用逗号分隔"),
    start_date: Optional[date] = Query(None, description="开始日期"),
    end_date: Optional[date] = Query(None, description="结束日期"),
    fields: Optional[str] = Query(None, description="字段列表，多个用逗号分隔"),
    limit: Optional[int] = Query(None, ge=1, le=10000, description="返回记录数限制"),
    manager: DataManager = Depends(get_data_manager)
) -> DataResponse:
    """
    查询数据
    
    Args:
        data_type: 数据类型
        symbols: 标的代码列表
        start_date: 开始日期
        end_date: 结束日期
        fields: 字段列表
        limit: 记录数限制
        manager: 数据管理器
        
    Returns:
        数据响应
    """
    try:
        # 解析参数
        symbol_list = symbols.split(',') if symbols else None
        field_list = fields.split(',') if fields else None
        
        # 构建查询请求
        query_request = DataQueryRequest(
            data_type=data_type,
            symbols=symbol_list,
            start_date=start_date,
            end_date=end_date,
            fields=field_list,
            limit=limit
        )
        
        # 执行查询
        result = await manager.query_data(
            data_type=query_request.data_type,
            symbols=query_request.symbols,
            start_date=query_request.start_date,
            end_date=query_request.end_date,
            fields=query_request.fields,
            filters=query_request.filters,
            limit=query_request.limit
        )
        
        return DataResponse(
            data=result.get("data", []),
            total=result.get("total", 0),
            data_type=data_type,
            query_time=datetime.now(),
            metadata=result.get("metadata", {})
        )
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"数据查询失败: {str(e)}")


@router.post("/query", response_model=DataResponse)
async def query_data_advanced(
    request: DataQueryRequest,
    manager: DataManager = Depends(get_data_manager)
) -> DataResponse:
    """
    高级数据查询
    
    Args:
        request: 查询请求
        manager: 数据管理器
        
    Returns:
        数据响应
    """
    try:
        # 执行查询
        result = await manager.query_data(
            data_type=request.data_type,
            symbols=request.symbols,
            start_date=request.start_date,
            end_date=request.end_date,
            fields=request.fields,
            filters=request.filters,
            limit=request.limit
        )
        
        return DataResponse(
            data=result.get("data", []),
            total=result.get("total", 0),
            data_type=request.data_type,
            query_time=datetime.now(),
            metadata=result.get("metadata", {})
        )
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"数据查询失败: {str(e)}")


@router.post("/upload")
async def upload_data(
    request: DataUploadRequest,
    file: UploadFile = File(...),
    manager: DataManager = Depends(get_data_manager)
) -> Dict[str, Any]:
    """
    上传数据文件
    
    Args:
        request: 上传请求
        file: 数据文件
        manager: 数据管理器
        
    Returns:
        上传结果
    """
    try:
        # 读取文件内容
        content = await file.read()
        
        # 处理数据上传
        result = await manager.upload_data(
            data_type=request.data_type,
            source=request.source,
            content=content,
            filename=file.filename,
            metadata=request.metadata,
            overwrite=request.overwrite
        )
        
        return {
            "message": "数据上传成功",
            "upload_id": result.get("upload_id"),
            "records_processed": result.get("records_processed", 0),
            "records_inserted": result.get("records_inserted", 0),
            "records_updated": result.get("records_updated", 0),
            "errors": result.get("errors", [])
        }
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"数据上传失败: {str(e)}")


@router.get("/sources", response_model=List[DataSourceInfo])
async def list_data_sources(
    data_type: Optional[str] = Query(None, description="按数据类型筛选"),
    status: Optional[str] = Query(None, description="按状态筛选"),
    manager: DataManager = Depends(get_data_manager)
) -> List[DataSourceInfo]:
    """
    获取数据源列表
    
    Args:
        data_type: 数据类型筛选
        status: 状态筛选
        manager: 数据管理器
        
    Returns:
        数据源信息列表
    """
    try:
        sources = await manager.list_data_sources(
            data_type=data_type,
            status=status
        )
        
        source_infos = []
        for source in sources:
            source_info = DataSourceInfo(
                source_id=source.get("source_id"),
                name=source.get("name"),
                description=source.get("description"),
                data_types=source.get("data_types", []),
                status=source.get("status", "unknown"),
                last_update=source.get("last_update"),
                update_frequency=source.get("update_frequency"),
                quality_score=source.get("quality_score", 0.0),
                metadata=source.get("metadata", {})
            )
            source_infos.append(source_info)
        
        return source_infos
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取数据源列表失败: {str(e)}")


@router.get("/sources/{source_id}", response_model=DataSourceInfo)
async def get_data_source(
    source_id: str = Path(..., description="数据源ID"),
    manager: DataManager = Depends(get_data_manager)
) -> DataSourceInfo:
    """
    获取数据源详情
    
    Args:
        source_id: 数据源ID
        manager: 数据管理器
        
    Returns:
        数据源信息
    """
    try:
        source = await manager.get_data_source(source_id)
        if not source:
            raise HTTPException(status_code=404, detail=f"数据源 {source_id} 不存在")
        
        return DataSourceInfo(
            source_id=source.get("source_id"),
            name=source.get("name"),
            description=source.get("description"),
            data_types=source.get("data_types", []),
            status=source.get("status", "unknown"),
            last_update=source.get("last_update"),
            update_frequency=source.get("update_frequency"),
            quality_score=source.get("quality_score", 0.0),
            metadata=source.get("metadata", {})
        )
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取数据源详情失败: {str(e)}")


@router.post("/validate", response_model=DataQualityReport)
async def validate_data(
    request: DataValidationRequest,
    checker: DataQualityChecker = Depends(get_data_quality_checker)
) -> DataQualityReport:
    """
    验证数据质量
    
    Args:
        request: 验证请求
        checker: 数据质量检查器
        
    Returns:
        数据质量报告
    """
    try:
        # 执行数据质量检查
        report = await checker.check_data_quality(
            data_type=request.data_type,
            data=request.data,
            rules=request.rules
        )
        
        return DataQualityReport(
            data_type=request.data_type,
            total_records=len(request.data),
            quality_score=report.get("quality_score", 0.0),
            issues=report.get("issues", []),
            recommendations=report.get("recommendations", []),
            check_time=datetime.now(),
            details=report.get("details", {})
        )
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"数据验证失败: {str(e)}")


@router.get("/quality/{data_type}", response_model=DataQualityReport)
async def get_data_quality_report(
    data_type: str = Path(..., description="数据类型"),
    start_date: Optional[date] = Query(None, description="开始日期"),
    end_date: Optional[date] = Query(None, description="结束日期"),
    checker: DataQualityChecker = Depends(get_data_quality_checker)
) -> DataQualityReport:
    """
    获取数据质量报告
    
    Args:
        data_type: 数据类型
        start_date: 开始日期
        end_date: 结束日期
        checker: 数据质量检查器
        
    Returns:
        数据质量报告
    """
    try:
        # 获取质量报告
        report = await checker.get_quality_report(
            data_type=data_type,
            start_date=start_date,
            end_date=end_date
        )
        
        return DataQualityReport(
            data_type=data_type,
            total_records=report.get("total_records", 0),
            quality_score=report.get("quality_score", 0.0),
            issues=report.get("issues", []),
            recommendations=report.get("recommendations", []),
            check_time=datetime.now(),
            details=report.get("details", {})
        )
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取质量报告失败: {str(e)}")


@router.get("/statistics/{data_type}", response_model=DataStatistics)
async def get_data_statistics(
    data_type: str = Path(..., description="数据类型"),
    start_date: Optional[date] = Query(None, description="开始日期"),
    end_date: Optional[date] = Query(None, description="结束日期"),
    manager: DataManager = Depends(get_data_manager)
) -> DataStatistics:
    """
    获取数据统计信息
    
    Args:
        data_type: 数据类型
        start_date: 开始日期
        end_date: 结束日期
        manager: 数据管理器
        
    Returns:
        数据统计信息
    """
    try:
        # 获取统计信息
        stats = await manager.get_data_statistics(
            data_type=data_type,
            start_date=start_date,
            end_date=end_date
        )
        
        return DataStatistics(
            data_type=data_type,
            record_count=stats.get("record_count", 0),
            date_range=stats.get("date_range", {}),
            field_statistics=stats.get("field_statistics", {}),
            update_frequency=stats.get("update_frequency", {}),
            quality_metrics=stats.get("quality_metrics", {})
        )
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取数据统计失败: {str(e)}")


@router.get("/cache/{key}")
async def get_cached_data(
    key: str = Path(..., description="缓存键"),
    cache: DataCache = Depends(get_data_cache)
) -> Dict[str, Any]:
    """
    获取缓存数据
    
    Args:
        key: 缓存键
        cache: 数据缓存
        
    Returns:
        缓存数据
    """
    try:
        data = await cache.get(key)
        if data is None:
            raise HTTPException(status_code=404, detail=f"缓存键 {key} 不存在或已过期")
        
        return {
            "key": key,
            "data": data,
            "retrieved_at": datetime.now()
        }
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取缓存数据失败: {str(e)}")


@router.post("/cache")
async def set_cached_data(
    request: CacheRequest,
    cache: DataCache = Depends(get_data_cache)
) -> Dict[str, str]:
    """
    设置缓存数据
    
    Args:
        request: 缓存请求
        cache: 数据缓存
        
    Returns:
        设置结果
    """
    try:
        success = await cache.set(
            key=request.key,
            value=request.data,
            ttl=request.ttl
        )
        
        if not success:
            raise HTTPException(status_code=500, detail="缓存设置失败")
        
        return {
            "message": f"缓存键 {request.key} 设置成功",
            "key": request.key,
            "ttl": str(request.ttl) if request.ttl else "永不过期"
        }
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"设置缓存数据失败: {str(e)}")


@router.delete("/cache/{key}")
async def delete_cached_data(
    key: str = Path(..., description="缓存键"),
    cache: DataCache = Depends(get_data_cache)
) -> Dict[str, str]:
    """
    删除缓存数据
    
    Args:
        key: 缓存键
        cache: 数据缓存
        
    Returns:
        删除结果
    """
    try:
        success = await cache.delete(key)
        if not success:
            raise HTTPException(status_code=404, detail=f"缓存键 {key} 不存在")
        
        return {"message": f"缓存键 {key} 已删除"}
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"删除缓存数据失败: {str(e)}")


@router.get("/types/available")
async def get_available_data_types(
    manager: DataManager = Depends(get_data_manager)
) -> List[Dict[str, Any]]:
    """
    获取可用的数据类型
    
    Args:
        manager: 数据管理器
        
    Returns:
        数据类型列表
    """
    try:
        data_types = await manager.get_available_data_types()
        
        type_infos = []
        for data_type in data_types:
            type_info = {
                "type": data_type.get("type"),
                "name": data_type.get("name"),
                "description": data_type.get("description"),
                "fields": data_type.get("fields", []),
                "sources": data_type.get("sources", []),
                "update_frequency": data_type.get("update_frequency"),
                "retention_period": data_type.get("retention_period")
            }
            type_infos.append(type_info)
        
        return type_infos
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取数据类型失败: {str(e)}")


@router.post("/refresh/{data_type}")
async def refresh_data(
    data_type: str = Path(..., description="数据类型"),
    source: Optional[str] = Query(None, description="指定数据源"),
    force: bool = Query(False, description="强制刷新"),
    manager: DataManager = Depends(get_data_manager)
) -> Dict[str, Any]:
    """
    刷新数据
    
    Args:
        data_type: 数据类型
        source: 指定数据源
        force: 强制刷新
        manager: 数据管理器
        
    Returns:
        刷新结果
    """
    try:
        result = await manager.refresh_data(
            data_type=data_type,
            source=source,
            force=force
        )
        
        return {
            "message": f"数据类型 {data_type} 刷新完成",
            "data_type": data_type,
            "source": source,
            "records_updated": result.get("records_updated", 0),
            "last_update": result.get("last_update"),
            "duration": result.get("duration", 0.0),
            "status": result.get("status", "success")
        }
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"数据刷新失败: {str(e)}")


@router.get("/health")
async def get_data_health(
    manager: DataManager = Depends(get_data_manager)
) -> Dict[str, Any]:
    """
    获取数据健康状态
    
    Args:
        manager: 数据管理器
        
    Returns:
        健康状态信息
    """
    try:
        health = await manager.get_health_status()
        
        return {
            "status": health.get("status", "unknown"),
            "data_sources": health.get("data_sources", {}),
            "cache_status": health.get("cache_status", {}),
            "database_status": health.get("database_status", {}),
            "last_check": health.get("last_check"),
            "issues": health.get("issues", []),
            "recommendations": health.get("recommendations", [])
        }
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取健康状态失败: {str(e)}")